#include "los.h"
#include "lvgl.h"
#include "touch.h"
#include "lcd.h"

#define LOS_LCD_THREAD_STACK_SIZE       (2000U)
//static uint8_t los_lcd_stack[LOS_LCD_THREAD_STACK_SIZE] = {0};
//static struct los_thread_t los_lcd_thread;

extern lv_img_dsc_t img_bubble_pattern;

struct los_lcd_t
{
    int32_t x1;
    int32_t y1;
    int32_t x2;
    int32_t y2;
    const lv_color_t * color_p;
};

static uint32_t los_last_touch_pos[2] = {0};
static bool_t los_touch_flag = false;
/**********************
 *  STATIC PROTOTYPES
 **********************/
static void write_create(lv_obj_t * parent);
static lv_res_t keyboard_open_close(lv_obj_t * ta);
static lv_res_t keyboard_hide_action(lv_obj_t * keyboard);
static void list_create(lv_obj_t * parent);
static void chart_create(lv_obj_t * parent);
static lv_res_t slider_action(lv_obj_t * slider);
static lv_res_t list_btn_action(lv_obj_t * slider);
#if LV_DEMO_SLIDE_SHOW
static void tab_switcher(void * tv);
#endif

/**********************
 *  STATIC VARIABLES
 **********************/
static lv_obj_t * chart;
static lv_obj_t * ta;
static lv_obj_t * kb;

static lv_style_t style_kb;
static lv_style_t style_kb_rel;
static lv_style_t style_kb_pr;


#define MONITOR_HOR_RES     LV_HOR_RES
#define MONITOR_VER_RES     LV_VER_RES

void
lcd_fill(struct los_lcd_t *lcd)
{
    uint16_t height,width;
    uint16_t i,j;
    lv_color_t * color_p = lcd->color_p;
    width=lcd->x2-lcd->x1+1;          //µÃµ½Ìî³äµÄ¿í¶È
    height=lcd->y2-lcd->y1+1;         //¸ß¶È
    for(i=0;i<height;i++)
    {
        LCD_SetCursor(lcd->x1,lcd->y1+i);     //ÉèÖÃ¹â±êÎ»ÖÃ
        LCD_WriteRAM_Prepare();     //¿ªÊ¼Ð´ÈëGRAM
        for(j=0;j<width;j++)
        {
            LCD->LCD_RAM=color_p->full;//Ð´ÈëÊý¾Ý
            color_p++;
        }
    }
}

// extern void GUI_LCD_Fill(int32_t sx,int32_t sy,int32_t ex,int32_t ey,lv_color_t color);
 extern void GUI_LCD_Map(int32_t sx,int32_t sy,int32_t ex,int32_t ey,const lv_color_t * color_map);
// extern void GUI_LCD_Flush(int32_t sx,int32_t sy,int32_t ex,int32_t ey,const lv_color_t * color_map);
/**
 * Flush a buffer to the display. Calls 'lv_flush_ready()' when finished
 * @param x1 left coordinate
 * @param y1 top coordinate
 * @param x2 right coordinate
 * @param y2 bottom coordinate
 * @param color_p array of colors to be flushed
 */
void
losbsp_lcd_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
    /*Return if the area is out the screen*/
    if(x2 < 0 || y2 < 0 || x1 > MONITOR_HOR_RES - 1 || y1 > MONITOR_VER_RES - 1) {
        lv_flush_ready();
        return;
    }
    GUI_LCD_Map(x1,y1,x2,y2,color_p);
//    struct los_lcd_t lcd;
//    lcd.x1 = x1;
//    lcd.x2 = x2;
//    lcd.y1 = y1;
//    lcd.y2 = y2;
//    lcd.color_p = color_p;
//    lcd_fill(&lcd);
    /*IMPORTANT! It must be called to tell the system the flush is ready*/
//    lv_flush_ready();
}

/**
 * Fill out the marked area with a color
 * @param x1 left coordinate
 * @param y1 top coordinate
 * @param x2 right coordinate
 * @param y2 bottom coordinate
 * @param color fill color
 */
void
losbsp_lcd_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color)
{
    /*Return if the area is out the screen*/
    if(x2 < 0) return;
    if(y2 < 0) return;
    if(x1 > MONITOR_HOR_RES - 1) return;
    if(y1 > MONITOR_VER_RES - 1) return;

    /*Truncate the area to the screen*/
    int32_t act_x1 = x1 < 0 ? 0 : x1;
    int32_t act_y1 = y1 < 0 ? 0 : y1;
    int32_t act_x2 = x2 > MONITOR_HOR_RES - 1 ? MONITOR_HOR_RES - 1 : x2;
    int32_t act_y2 = y2 > MONITOR_VER_RES - 1 ? MONITOR_VER_RES - 1 : y2;

    int32_t x;
    int32_t y;
    uint16_t color16 = lv_color_to16(color);

    for(x = act_x1; x <= act_x2; x++) {
        for(y = act_y1; y <= act_y2; y++) {
            LCD_Fast_DrawPoint(y, MONITOR_HOR_RES - x,color16);
        }
    }

}

/**
 * Put a color map to the marked area
 * @param x1 left coordinate
 * @param y1 top coordinate
 * @param x2 right coordinate
 * @param y2 bottom coordinate
 * @param color_p an array of colors
 */
void
losbsp_lcd_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
    /*Return if the area is out the screen*/
    if(x2 < 0) return;
    if(y2 < 0) return;
    if(x1 > MONITOR_HOR_RES - 1) return;
    if(y1 > MONITOR_VER_RES - 1) return;

    /*Truncate the area to the screen*/
    int32_t act_x1 = x1 < 0 ? 0 : x1;
    int32_t act_y1 = y1 < 0 ? 0 : y1;
    int32_t act_x2 = x2 > MONITOR_HOR_RES - 1 ? MONITOR_HOR_RES - 1 : x2;
    int32_t act_y2 = y2 > MONITOR_VER_RES - 1 ? MONITOR_VER_RES - 1 : y2;

    int32_t x;
    int32_t y;

    for(y = act_y1; y <= act_y2; y++) {
        for(x = act_x1; x <= act_x2; x++) {
            uint16_t color16 = lv_color_to16(*color_p);
            LCD_Fast_DrawPoint( y, MONITOR_HOR_RES - x,color16);
            color_p++;
        }

        color_p += x2 - act_x2;
    }

}

/**
 * Get the current position and state of the mouse
 * @param data store the mouse data here
 * @return false: because the points are not buffered, so no more data to be read
 */
bool mouse_read(lv_indev_data_t * data)
{
    /*Store the collected data*/
    data->point.x = (int16_t)los_last_touch_pos[0];
    data->point.y = (int16_t)los_last_touch_pos[1];
    data->state = los_touch_flag ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
    los_touch_flag = false;
    return false;
}

void ctp_test(void)
{
    u8 t=0;
    u8 i=0;
    u32 lastpos[2] = {0,0};
    tp_dev.scan(0);
    for(t=0;t<5;t++)
    {
        if((tp_dev.sta)&(1<<t))
        {
            if(tp_dev.x[t]<lcddev.width&&tp_dev.y[t]<lcddev.height)
            {
                i++;
                lastpos[0] += tp_dev.x[t];
                lastpos[1] += tp_dev.y[t];
            }
        }
    }
    if(i!=0)
    {
        los_touch_flag = true;
        lastpos[0] /= i;
        lastpos[1] /= i;
        los_last_touch_pos[0] = lastpos[0];
        los_last_touch_pos[1] = lastpos[1];
    }
}

static void hal_init(void)
{
    lv_disp_drv_t disp_drv;
    LCD_Init();
    LCD_Display_Dir(1);
    LCD_Scan_Dir(L2R_U2D);
    tp_dev.init();
    lv_disp_drv_init(&disp_drv);            /*Basic initialization*/
    disp_drv.disp_flush = losbsp_lcd_flush;    /*Used when `LV_VDB_SIZE != 0` in lv_conf.h (buffered drawing)*/
    disp_drv.disp_fill = losbsp_lcd_fill;      /*Used when `LV_VDB_SIZE == 0` in lv_conf.h (unbuffered drawing)*/
    disp_drv.disp_map = losbsp_lcd_map;        /*Used when `LV_VDB_SIZE == 0` in lv_conf.h (unbuffered drawing)*/
    lv_disp_drv_register(&disp_drv);

    lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);          /*Basic initialization*/
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read = mouse_read;         /*This function will be called periodically (by the library) to get the mouse position and state*/
    lv_indev_t * mouse_indev = lv_indev_drv_register(&indev_drv);

    /*Set a cursor for the mouse*/
    LV_IMG_DECLARE(mouse_cursor_icon);                          /*Declare the image file.*/
    lv_obj_t * cursor_obj =  lv_img_create(lv_scr_act(), NULL); /*Create an image object for the cursor */
    lv_img_set_src(cursor_obj, &mouse_cursor_icon);             /*Set the image source*/
    lv_indev_set_cursor(mouse_indev, cursor_obj);               /*Connect the image  object to the driver*/


}

/**********************
 *   STATIC FUNCTIONS
 **********************/

static void write_create(lv_obj_t * parent)
{
    lv_page_set_style(parent, LV_PAGE_STYLE_BG, &lv_style_transp_fit);
    lv_page_set_style(parent, LV_PAGE_STYLE_SCRL, &lv_style_transp_fit);

    lv_page_set_sb_mode(parent, LV_SB_MODE_OFF);

    static lv_style_t style_ta;
    lv_style_copy(&style_ta, &lv_style_pretty);
    style_ta.body.opa = LV_OPA_30;
    style_ta.body.radius = 0;
    style_ta.text.color = LV_COLOR_HEX3(0x222);

    ta = lv_ta_create(parent, NULL);
    lv_obj_set_size(ta, lv_page_get_scrl_width(parent), lv_obj_get_height(parent) / 2);
    lv_ta_set_style(ta, LV_TA_STYLE_BG, &style_ta);
    lv_ta_set_text(ta, "");
    lv_page_set_rel_action(ta, keyboard_open_close);

    lv_style_copy(&style_kb, &lv_style_plain);
    style_kb.body.opa = LV_OPA_70;
    style_kb.body.main_color = LV_COLOR_HEX3(0x333);
    style_kb.body.grad_color = LV_COLOR_HEX3(0x333);
    style_kb.body.padding.hor = 0;
    style_kb.body.padding.ver = 0;
    style_kb.body.padding.inner = 0;

    lv_style_copy(&style_kb_rel, &lv_style_plain);
    style_kb_rel.body.empty = 1;
    style_kb_rel.body.radius = 0;
    style_kb_rel.body.border.width = 1;
    style_kb_rel.body.border.color = LV_COLOR_SILVER;
    style_kb_rel.body.border.opa = LV_OPA_50;
    style_kb_rel.body.main_color = LV_COLOR_HEX3(0x333);    /*Recommended if LV_VDB_SIZE == 0 and bpp > 1 fonts are used*/
    style_kb_rel.body.grad_color = LV_COLOR_HEX3(0x333);
    style_kb_rel.text.color = LV_COLOR_WHITE;

    lv_style_copy(&style_kb_pr, &lv_style_plain);
    style_kb_pr.body.radius = 0;
    style_kb_pr.body.opa = LV_OPA_50;
    style_kb_pr.body.main_color = LV_COLOR_WHITE;
    style_kb_pr.body.grad_color = LV_COLOR_WHITE;
    style_kb_pr.body.border.width = 1;
    style_kb_pr.body.border.color = LV_COLOR_SILVER;

    keyboard_open_close(ta);
}

static lv_res_t keyboard_open_close(lv_obj_t * text_area)
{
    (void) text_area;    /*Unused*/

    lv_obj_t * parent = lv_obj_get_parent(lv_obj_get_parent(ta));   /*Test area is on the scrollable part of the page but we need the page itself*/

    if(kb) {
        return keyboard_hide_action(kb);
    } else {

        kb = lv_kb_create(parent, NULL);
        lv_obj_set_size(kb, lv_page_get_scrl_width(parent), lv_obj_get_height(parent) / 2);
        lv_obj_align(kb, ta, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
        lv_kb_set_ta(kb, ta);
        lv_kb_set_style(kb, LV_KB_STYLE_BG, &style_kb);
        lv_kb_set_style(kb, LV_KB_STYLE_BTN_REL, &style_kb_rel);
        lv_kb_set_style(kb, LV_KB_STYLE_BTN_PR, &style_kb_pr);
        lv_kb_set_hide_action(kb, keyboard_hide_action);
        lv_kb_set_ok_action(kb, keyboard_hide_action);

#if USE_LV_ANIMATION
        lv_obj_animate(kb, LV_ANIM_FLOAT_BOTTOM | LV_ANIM_IN, 300, 0, NULL);
#endif
        return LV_RES_OK;
    }
}

/**
 * Called when the close or ok button is pressed on the keyboard
 * @param keyboard pointer to the keyboard
 * @return
 */
static lv_res_t keyboard_hide_action(lv_obj_t * keyboard)
{
    (void) keyboard;    /*Unused*/

#if USE_LV_ANIMATION
    lv_obj_animate(kb, LV_ANIM_FLOAT_BOTTOM | LV_ANIM_OUT, 300, 0, (void(*)(lv_obj_t *))lv_obj_del);
    kb = NULL;
    return LV_RES_OK;
#else
    lv_obj_del(kb);
    kb = NULL;
    return LV_RES_INV;
#endif
}

static void list_create(lv_obj_t * parent)
{
    lv_page_set_style(parent, LV_PAGE_STYLE_BG, &lv_style_transp_fit);
    lv_page_set_style(parent, LV_PAGE_STYLE_SCRL, &lv_style_transp_fit);

    lv_page_set_scrl_fit(parent, false, false);
    lv_page_set_scrl_height(parent, lv_obj_get_height(parent));
    lv_page_set_sb_mode(parent, LV_SB_MODE_OFF);

    /*Create styles for the buttons*/
    static lv_style_t style_btn_rel;
    static lv_style_t style_btn_pr;
    lv_style_copy(&style_btn_rel, &lv_style_btn_rel);
    style_btn_rel.body.main_color = LV_COLOR_HEX3(0x333);
    style_btn_rel.body.grad_color = LV_COLOR_BLACK;
    style_btn_rel.body.border.color = LV_COLOR_SILVER;
    style_btn_rel.body.border.width = 1;
    style_btn_rel.body.border.opa = LV_OPA_50;
    style_btn_rel.body.radius = 0;

    lv_style_copy(&style_btn_pr, &style_btn_rel);
    style_btn_pr.body.main_color = LV_COLOR_MAKE(0x55, 0x96, 0xd8);
    style_btn_pr.body.grad_color = LV_COLOR_MAKE(0x37, 0x62, 0x90);
    style_btn_pr.text.color = LV_COLOR_MAKE(0xbb, 0xd5, 0xf1);

    lv_obj_t * list = lv_list_create(parent, NULL);
    lv_obj_set_height(list, 2 * lv_obj_get_height(parent) / 3);
    lv_list_set_style(list, LV_LIST_STYLE_BG, &lv_style_transp_tight);
    lv_list_set_style(list, LV_LIST_STYLE_SCRL, &lv_style_transp_tight);
    lv_list_set_style(list, LV_LIST_STYLE_BTN_REL, &style_btn_rel);
    lv_list_set_style(list, LV_LIST_STYLE_BTN_PR, &style_btn_pr);
    lv_obj_align(list, NULL, LV_ALIGN_IN_TOP_MID, 0, LV_DPI / 4);

    lv_list_add(list, SYMBOL_FILE, "New", list_btn_action);
    lv_list_add(list, SYMBOL_DIRECTORY, "Open", list_btn_action);
    lv_list_add(list, SYMBOL_TRASH, "Delete", list_btn_action);
    lv_list_add(list, SYMBOL_EDIT, "Edit", list_btn_action);
    lv_list_add(list, SYMBOL_SAVE, "Save", list_btn_action);
    lv_list_add(list, SYMBOL_WIFI, "WiFi", list_btn_action);
    lv_list_add(list, SYMBOL_GPS, "GPS", list_btn_action);

    lv_obj_t * mbox = lv_mbox_create(parent, NULL);
    lv_mbox_set_text(mbox, "Click a button to copy its text to the Text area ");
    lv_obj_set_width(mbox, LV_HOR_RES - LV_DPI);
    static const char * mbox_btns[] = {"Got it", ""};
    lv_mbox_add_btns(mbox, mbox_btns, NULL);    /*The default action is close*/
    lv_obj_align(mbox, parent, LV_ALIGN_IN_TOP_MID, 0, LV_DPI / 2);
}

static void chart_create(lv_obj_t * parent)
{
    lv_page_set_style(parent, LV_PAGE_STYLE_BG, &lv_style_transp_fit);
    lv_page_set_style(parent, LV_PAGE_STYLE_SCRL, &lv_style_transp_fit);

    lv_page_set_scrl_fit(parent, false, false);
    lv_page_set_scrl_height(parent, lv_obj_get_height(parent));
    lv_page_set_sb_mode(parent, LV_SB_MODE_OFF);

    static lv_style_t style_chart;
    lv_style_copy(&style_chart, &lv_style_pretty);
    style_chart.body.opa = LV_OPA_60;
    style_chart.body.radius = 0;
    style_chart.line.color = LV_COLOR_GRAY;

    chart = lv_chart_create(parent, NULL);
    lv_obj_set_size(chart, 2 * lv_obj_get_width(parent) / 3, lv_obj_get_height(parent) / 2);
    lv_obj_align(chart, NULL,  LV_ALIGN_IN_TOP_MID, 0, LV_DPI / 4);
    lv_chart_set_type(chart, LV_CHART_TYPE_COLUMN);
    lv_chart_set_style(chart, &style_chart);
    lv_chart_set_series_opa(chart, LV_OPA_70);
    lv_chart_series_t * ser1;
    ser1 = lv_chart_add_series(chart, LV_COLOR_RED);
    lv_chart_set_next(chart, ser1, 40);
    lv_chart_set_next(chart, ser1, 30);
    lv_chart_set_next(chart, ser1, 47);
    lv_chart_set_next(chart, ser1, 59);
    lv_chart_set_next(chart, ser1, 59);
    lv_chart_set_next(chart, ser1, 31);
    lv_chart_set_next(chart, ser1, 55);
    lv_chart_set_next(chart, ser1, 70);
    lv_chart_set_next(chart, ser1, 82);

    /*Create a bar, an indicator and a knob style*/
    static lv_style_t style_bar;
    static lv_style_t style_indic;
    static lv_style_t style_knob;

    lv_style_copy(&style_bar, &lv_style_pretty);
    style_bar.body.main_color =  LV_COLOR_BLACK;
    style_bar.body.grad_color =  LV_COLOR_GRAY;
    style_bar.body.radius = LV_RADIUS_CIRCLE;
    style_bar.body.border.color = LV_COLOR_WHITE;
    style_bar.body.opa = LV_OPA_60;
    style_bar.body.padding.hor = 0;
    style_bar.body.padding.ver = LV_DPI / 10;

    lv_style_copy(&style_indic, &lv_style_pretty);
    style_indic.body.grad_color =  LV_COLOR_MAROON;
    style_indic.body.main_color =  LV_COLOR_RED;
    style_indic.body.radius = LV_RADIUS_CIRCLE;
    style_indic.body.shadow.width = LV_DPI / 10;
    style_indic.body.shadow.color = LV_COLOR_RED;
    style_indic.body.padding.hor = LV_DPI / 30;
    style_indic.body.padding.ver = LV_DPI / 30;

    lv_style_copy(&style_knob, &lv_style_pretty);
    style_knob.body.radius = LV_RADIUS_CIRCLE;
    style_knob.body.opa = LV_OPA_70;

    /*Create a second slider*/
    lv_obj_t * slider = lv_slider_create(parent, NULL);
    lv_slider_set_style(slider, LV_SLIDER_STYLE_BG, &style_bar);
    lv_slider_set_style(slider, LV_SLIDER_STYLE_INDIC, &style_indic);
    lv_slider_set_style(slider, LV_SLIDER_STYLE_KNOB, &style_knob);
    lv_obj_set_size(slider, lv_obj_get_width(chart), LV_DPI / 3);
    lv_obj_align(slider, chart, LV_ALIGN_OUT_BOTTOM_MID, 0, (LV_VER_RES - chart->coords.y2 - lv_obj_get_height(slider)) / 2); /*Align to below the chart*/
    lv_slider_set_action(slider, slider_action);
    lv_slider_set_range(slider, 10, 1000);
    lv_slider_set_value(slider, 700);
    slider_action(slider);          /*Simulate a user value set the refresh the chart*/
}

/**
 * Called when a new value on the slider on the Chart tab is set
 * @param slider pointer to the slider
 * @return LV_RES_OK because the slider is not deleted in the function
 */
static lv_res_t slider_action(lv_obj_t * slider)
{
    int16_t v = lv_slider_get_value(slider);
    v = 1000 * 100 / v; /*Convert to range modify values linearly*/
    lv_chart_set_range(chart, 0, v);

    return LV_RES_OK;
}

/**
 * Called when a a list button is clicked on the List tab
 * @param btn pointer to a list button
 * @return LV_RES_OK because the button is not deleted in the function
 */
static lv_res_t list_btn_action(lv_obj_t * btn)
{
    lv_ta_add_char(ta, '\n');
    lv_ta_add_text(ta, lv_list_get_btn_text(btn));

    return LV_RES_OK;
}

void
demo_create(void)
{
    lv_obj_t * wp = lv_img_create(lv_scr_act(), NULL);
   lv_img_set_src(wp, &img_bubble_pattern);
   lv_obj_set_width(wp, LV_HOR_RES * 2);
   lv_obj_set_protect(wp, LV_PROTECT_POS);
   static lv_style_t style_tv_btn_bg;
   lv_style_copy(&style_tv_btn_bg, &lv_style_plain);
   style_tv_btn_bg.body.main_color = LV_COLOR_HEX(0x487fb7);
   style_tv_btn_bg.body.grad_color = LV_COLOR_HEX(0x487fb7);
   style_tv_btn_bg.body.padding.ver = 0;

   static lv_style_t style_tv_btn_rel;
   lv_style_copy(&style_tv_btn_rel, &lv_style_btn_rel);
   style_tv_btn_rel.body.empty = 1;
   style_tv_btn_rel.body.border.width = 0;

   static lv_style_t style_tv_btn_pr;
   lv_style_copy(&style_tv_btn_pr, &lv_style_btn_pr);
   style_tv_btn_pr.body.radius = 0;
   style_tv_btn_pr.body.opa = LV_OPA_50;
   style_tv_btn_pr.body.main_color = LV_COLOR_WHITE;
   style_tv_btn_pr.body.grad_color = LV_COLOR_WHITE;
   style_tv_btn_pr.body.border.width = 0;
   style_tv_btn_pr.text.color = LV_COLOR_GRAY;

   lv_obj_t * tv = lv_tabview_create(lv_scr_act(), NULL);

   lv_obj_set_parent(wp, ((lv_tabview_ext_t *) tv->ext_attr)->content);
   lv_obj_set_pos(wp, 0, -5);

   lv_obj_t * tab1 = lv_tabview_add_tab(tv, "Write");
   lv_obj_t * tab2 = lv_tabview_add_tab(tv, "List");
   lv_obj_t * tab3 = lv_tabview_add_tab(tv, "Chart");

   lv_tabview_set_style(tv, LV_TABVIEW_STYLE_BTN_BG, &style_tv_btn_bg);
   lv_tabview_set_style(tv, LV_TABVIEW_STYLE_INDIC, &lv_style_plain);
   lv_tabview_set_style(tv, LV_TABVIEW_STYLE_BTN_REL, &style_tv_btn_rel);
   lv_tabview_set_style(tv, LV_TABVIEW_STYLE_BTN_PR, &style_tv_btn_pr);
   lv_tabview_set_style(tv, LV_TABVIEW_STYLE_BTN_TGL_REL, &style_tv_btn_rel);
   lv_tabview_set_style(tv, LV_TABVIEW_STYLE_BTN_TGL_PR, &style_tv_btn_pr);

   write_create(tab1);
   list_create(tab2);
   chart_create(tab3);
}

static void
lcd_thread(uint32_t *param)
{
    param = *(&param);
    while(1)
    {
        lv_task_handler();
        ctp_test();
        los_delay_ms(5);
    }
}

void
ui_init(void)
{
    struct los_thread_t *__lcd_thread = NULL;
    lv_init();
    hal_init();
    demo_create();
    __lcd_thread = los_resiger_thread(lcd_thread,NULL,LOS_LCD_THREAD_STACK_SIZE,124);
    if(__lcd_thread!=NULL)
        los_start_thread(__lcd_thread);
}
